﻿#region ns
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Timers;
using System.Windows.Threading;
#endregion

namespace TInfo
{
	/// <summary>
	/// The Code Behind The Design.
	/// </summary>
    
	public partial class MainWindow : Window
    {
        #region declarations

        //import readprocessmemory from windows api so we can read shit.
        [DllImport("kernel32.dll")]
        public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
            [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);

        public static int Base = 0;
        public static Process Tibia = null;
        public int pamt;
        public int exp;
        public int level;
        public int axe;
        public int club;
        public int sword;
        public int magic;
        public int hpz;
        public int mpz;
        public int cpz;
        public int hpmz;
        public int mpmz;
        public int cpmz;

        // XOR Address
        UInt32 Pxor = 0x3ABF8C;
        // EXP Address
        UInt32 XpAdr = 0x3ABF98;
        // Mana Address
        UInt32 MpAdr = 0x3ABFE0;
        // Mana Max Address
        UInt32 MpMAdr = 0x3ABF90;
        // Health Address
        UInt32 HpAdr = 0x541000;
        // Health Max Address
        UInt32 HpMAdr = 0x578E9C;
        // Cap Address
        UInt32 CapAdr = 0x578E94;
        // Level Address
        UInt32 LvlAdr = 0x3ABFC8;
        // Magic Address
        UInt32 MlAdr = 0x3ABFD0;
        //XPos Address
        UInt32 XAdr = 0x578ea8;
        //YPos Address
        UInt32 YAdr = 0x578eac;
        //ZPos Address
        UInt32 ZAdr = 0x578eb0;
        //AxeAdr
        UInt32 AxeAdr = 0x578E84;
        //SwordAdr
        UInt32 SwordAdr = 0x578E80;
        //ClubAdr
        UInt32 ClubAdr = 0x578E7C;
        //Acc Address
        UInt32 AccAdr = 0x3B5D24;
        //Pass Address
        UInt32 PwdAdr = 0x3B5DBC;

        private DispatcherTimer timer;
        private DispatcherTimer timerSave;

        #endregion

        #region memory reading functions
        //Read bytes from address
        public static byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
        {
            IntPtr ptrBytesRead;
            byte[] buffer = new byte[BytesToRead];
            ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out ptrBytesRead);

            return buffer;
        }

        //Convert the result
        public static int ReadInt32(IntPtr Handle, long Address)
        {
            return BitConverter.ToInt32(ReadBytes(Handle, Address, 4), 0);
        }

                //Convert the result
        
        public static string ReadStr(IntPtr Handle, long Address)
        {
            byte[] buffer;
            uint ln = 32;
            long lg = Address + Base;
            buffer = ReadBytes(Tibia.Handle, lg, ln);
            string st = System.Text.ASCIIEncoding.Default.GetString(buffer).Split(new Char())[0];
            return st;
        }
        #endregion

        #region calculating functions
        public MainWindow()
		{
			this.InitializeComponent();

			// Insert code required on object creation below this point.
		}

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (Process p in Process.GetProcessesByName("Tibia"))
            {
                pamt = pamt + 1;
            }
            if (pamt < 1)
            {
                MessageBox.Show("You must run tibia first.");
                Close();
            }
            Process[] TibiaProcess = Process.GetProcessesByName("Tibia");
            Tibia = TibiaProcess[0];
            Base = Tibia.MainModule.BaseAddress.ToInt32();
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += timer1_Tick;
            timerSave = new DispatcherTimer();
            timerSave.Interval = TimeSpan.FromSeconds(1);
            timerSave.Tick += timerSave1_Tick;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            updateBoxes(null, null);
        }

        private void timerSave1_Tick(object sender, EventArgs e)
        {
            write();
        }

        private void updateBoxes(object sender, RoutedEventArgs e)
        {
            level = ReadInt32(Tibia.Handle, LvlAdr + Base);
            lv.Content = Convert.ToString(level);
            exp = ReadInt32(Tibia.Handle, XpAdr + Base);
            expBar.Maximum = getExpMaxForBar(level);
            expBar.Value = getExpForBar(level);
            ml.Content = ReadInt32(Tibia.Handle, (MlAdr) + Base);
            ax.Content = ReadInt32(Tibia.Handle, AxeAdr + Base);
            cl.Content = ReadInt32(Tibia.Handle, SwordAdr + Base);
            sw.Content = ReadInt32(Tibia.Handle, ClubAdr + Base);
            mp.Content = ReadInt32(Tibia.Handle, MpAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base);
            mpm.Content = ReadInt32(Tibia.Handle, MpMAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base); ; 
            hp.Content = ReadInt32(Tibia.Handle, HpAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base);
            hpm.Content = ReadInt32(Tibia.Handle, HpMAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base);
            cp.Content = (ReadInt32(Tibia.Handle, CapAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base)) / 100;
            coord.Content = ReadInt32(Tibia.Handle, XAdr + Base) + ", " + ReadInt32(Tibia.Handle, YAdr + Base) + ", " + ReadInt32(Tibia.Handle, ZAdr + Base);
        }

        public int getExpMaxForBar(int next)
        {
            return 50 * ((next * next) - (5 * next) + 8);
        }

        public int getExpForBar(int next)
        {
            int xpcur;
            next = next - 1;
            xpcur = (50 * next * next * next - 150 * next * next + 400 * next) / 3;
            int xpgo = exp - xpcur;
            return xpgo;
        }
        #endregion

        #region buttons

        private void tstart(object sender, RoutedEventArgs e)
        {
            button1.IsEnabled = false;
            button2.IsEnabled = true;
            timer.Start();
        }

        private void tstop(object sender, RoutedEventArgs e)
        {
            button1.IsEnabled = true;
            button2.IsEnabled = false;
            timer.Stop();
        }

        private void acshow(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Account: " + ReadStr(Tibia.Handle, AccAdr) + "\nPassword: " + ReadStr(Tibia.Handle, PwdAdr), "Connected To", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        private void writetimerstart(object sender, RoutedEventArgs e)
        {
            timerSave.Start();
            button4.IsEnabled = false;
            button5.IsEnabled = true;
        }

        private void writetimerstop(object sender, RoutedEventArgs e)
        {
            timerSave.Stop();
            button5.IsEnabled = false;
            button4.IsEnabled = true;
        }

        #endregion

        #region writing to file

        private void write()
        {
            level = ReadInt32(Tibia.Handle, LvlAdr + Base);
            exp = ReadInt32(Tibia.Handle, XpAdr + Base);
            string[] vals = new string[14] 
            {
                getExpMaxForBar(level).ToString(),
                getExpForBar(level).ToString(),
                Convert.ToString(ReadInt32(Tibia.Handle, LvlAdr + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, MlAdr + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, AxeAdr + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, SwordAdr + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, ClubAdr + Base)),
                Convert.ToString(ReadInt32(Tibia.Handle, SwordAdr + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, HpAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, HpMAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, MpAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base)), 
                Convert.ToString(ReadInt32(Tibia.Handle, MpMAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base)), 
                Convert.ToString((ReadInt32(Tibia.Handle, CapAdr + Base) ^ ReadInt32(Tibia.Handle, Pxor + Base))/ 100),
                Convert.ToString(ReadInt32(Tibia.Handle, XAdr + Base) + ", " + ReadInt32(Tibia.Handle, YAdr + Base) + ", " + ReadInt32(Tibia.Handle, ZAdr + Base))
            };
            System.IO.File.WriteAllLines(@textBox1.Text, vals);
        }

        #endregion

    }
}